/* dialogs.c is part of VIP program
 * Written by J. Salvador Arias, 2010
 *      CONICET, INSUE, Instituto Miguel Lillo,
 *      Miguel Lillo 205, S.M. de Tucuman (4000)
 *      Tucuman, Argentina
 *      e-mail: jsalarias@csnat.unt.edu.ar
 *
 * VIP is a free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation and
 * Creative Commons.
 *
 * This file and the VIP program is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * To view a copy of this license, visit
 * http://creativecommons.org/licenses/GPL/2.0/
 * or send a letter to
 * Creative Commons, 171 Second Street, Suite 300,
 * San Francisco, California, 94105, USA.
 */

#include "wins.h"
#include "dialogs.h"
#include "out.h"
#include "parser.h"
#include "biogeo.h"
#include "grid.h"
#include <string.h>

GRIDDIALOG* GridDialog (SREAL size, SINTEGER fill, SFLAG editable) {
 GRIDDIALOG* toRet;
 GtkWidget* separator;
 gchar* text;

 toRet = g_slice_alloc (sizeof (GRIDDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Grid settings", GTK_WINDOW (GETMAINWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> sizeEntry = CreateEntry ("Grid Size", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 toRet -> fillEntry = CreateEntry ("Maximum fill", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 toRet -> mooreRadio = gtk_radio_button_new_with_mnemonic (NULL, "_Moore neightborhood");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> mooreRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> mooreRadio);
 toRet -> vonneRadio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (toRet -> mooreRadio),
                                          "_Von Neumann neighborhood");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> vonneRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> vonneRadio);

 text = g_strdup_printf ("%.4f", size);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> sizeEntry), text);
 g_free (text);
 text = g_strdup_printf ("%ld", fill);
 gtk_entry_set_text (GTK_ENTRY (toRet -> fillEntry), text);
 g_free (text);
 if (GETGRIDMODE & MOORE_NEIGHBORS)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> mooreRadio), TRUE);
 else if (GETGRIDMODE & VONNEUMANN_NEIGHBORS)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> vonneRadio), TRUE);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> sizeEntry), editable);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> fillEntry), editable);
 gtk_widget_set_sensitive (toRet -> mooreRadio, editable);
 gtk_widget_set_sensitive (toRet -> vonneRadio, editable);
 return toRet;
}

void DestroyGridDialog (GRIDDIALOG* grid) {
 gtk_widget_destroy (grid -> dialog);
 g_slice_free1 (sizeof (GRIDDIALOG), grid);
}

ENTRYDIALOG* CounterEntryDialog (GtkWindow* parent, SCOUNTER count, gchar* name, gchar* caption) {
 ENTRYDIALOG* toRet;
 GtkWidget* separator;
 gchar* text;

 toRet = g_slice_alloc (sizeof (ENTRYDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons (name, GTK_WINDOW (parent),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> entry = CreateEntry (caption, GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 text = g_strdup_printf ("%ld", count);
 gtk_entry_set_text (GTK_ENTRY (toRet -> entry), text);
 g_free (text);

 return toRet;
}

ENTRYDIALOG* RealEntryDialog (GtkWindow* parent, SREAL number, gchar* name, gchar* caption) {
 ENTRYDIALOG* toRet;
 GtkWidget* separator;
 gchar* text;

 toRet = g_slice_alloc (sizeof (ENTRYDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons (name, GTK_WINDOW (parent),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> entry = CreateEntry (caption, GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 text = g_strdup_printf ("%.4f", number);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> entry), text);
 g_free (text);

 return toRet;
}

ENTRYDIALOG* TextEntryDialog (GtkWindow* parent, gchar* text, gchar* name, gchar* caption) {
 ENTRYDIALOG* toRet;
 GtkWidget* separator;

 toRet = g_slice_alloc (sizeof (ENTRYDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons (name, GTK_WINDOW (parent),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> entry = CreateEntry (caption, GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 gtk_entry_set_text (GTK_ENTRY (toRet -> entry), text);
 return toRet;
}

void DestroyEntryDialog (ENTRYDIALOG* toDel) {
 gtk_widget_destroy (toDel -> dialog);
 g_slice_free1 (sizeof (ENTRYDIALOG), toDel);
}

CENTREDIALOG* CentreDialog () {
 CENTREDIALOG* toRet;
 GtkWidget* separator;

 toRet = g_slice_alloc (sizeof (CENTREDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Centre map", GTK_WINDOW (GETMAPWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
 toRet -> latEntry = CreateEntry ("Latitude", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 toRet -> lonEntry = CreateEntry ("Longitude", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 gtk_entry_set_text (GTK_ENTRY (toRet -> latEntry), "0.0000");
 gtk_entry_set_text (GTK_ENTRY (toRet -> lonEntry), "0.0000");
 return toRet;
}

void DestroyCentreDialog (CENTREDIALOG* centre) {
 gtk_widget_destroy (centre -> dialog);
 g_slice_free1 (sizeof (CENTREDIALOG), centre);
}

MAPLIMITSDIALOG* MapLimitsDialog (SREAL n, SREAL s, SREAL e, SREAL w) {
 MAPLIMITSDIALOG* toRet;
 GtkWidget* separator;
 gchar* text;

 toRet = g_slice_alloc (sizeof (MAPLIMITSDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Set map limits", GTK_WINDOW (GETMAPWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> northEntry = CreateEntry ("North (Latitude)", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 toRet -> southEntry = CreateEntry ("South (Latitude)", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 toRet -> eastEntry = CreateEntry ("East (Longitude)", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 toRet -> westEntry = CreateEntry ("West (Longitude)", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 text = g_strdup_printf ("%.4f", n);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> northEntry), text);
 g_free (text);
 text = g_strdup_printf ("%.4f", s);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> southEntry), text);
 g_free (text);
 text = g_strdup_printf ("%.4f", e);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> eastEntry), text);
 g_free (text);
 text = g_strdup_printf ("%.4f", w);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (toRet -> westEntry), text);
 g_free (text);
 return toRet;
}

void DestroyMapLimitsDialog (MAPLIMITSDIALOG* mapLimits) {
 gtk_widget_destroy (mapLimits -> dialog);
 g_slice_free1 (sizeof (CENTREDIALOG), mapLimits);
}

SEARCHDIALOG* SearchDialog () {
 SEARCHDIALOG* toRet;
 GtkWidget* separator;
 GtkWidget* vBox;
 GtkWidget* hBox;
 gchar* text;

 toRet = g_slice_alloc (sizeof (SEARCHDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Search", GTK_WINDOW (GETMAINWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 hBox = gtk_hbox_new (FALSE, 25);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> iterEntry = CreateEntry ("Iterations", GTK_BOX (vBox));
 toRet -> holdEntry = CreateEntry ("Hold (per iteration)", GTK_BOX (vBox));
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> pageCheck = gtk_check_button_new_with_mnemonic ("_Page\'s heuristic");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> pageCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> pageCheck);
 toRet -> flipCheck = gtk_check_button_new_with_mnemonic ("_Flip nodes");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> flipCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> flipCheck);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (vBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 toRet -> consCheck = gtk_check_button_new_with_mnemonic ("_OR constrained search");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> consCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> consCheck);
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), hBox, TRUE, TRUE, 2);
 gtk_widget_show (hBox);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 hBox = gtk_hbox_new (FALSE, 10);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> noSecRadio = gtk_radio_button_new_with_mnemonic (NULL, "_No sectors");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> noSecRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> noSecRadio);
 toRet -> startSecRadio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (toRet -> noSecRadio), "_Start with a sector");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> startSecRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> startSecRadio);
 toRet -> secRadio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (toRet -> noSecRadio), "_Full sector search");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> secRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> secRadio);
 toRet -> secSizeEntry = CreateEntry ("Sector size", GTK_BOX (vBox));
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 separator = gtk_vseparator_new ();
 gtk_box_pack_start (GTK_BOX (hBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> noAnnealRadio = gtk_radio_button_new_with_mnemonic (NULL, "N_o annealing");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> noAnnealRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> noAnnealRadio);
 toRet -> blindAnnealRadio = gtk_radio_button_new_with_mnemonic_from_widget
                             (GTK_RADIO_BUTTON (toRet -> noAnnealRadio), "_Blind annealing");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> blindAnnealRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> blindAnnealRadio);
 toRet -> gibbsAnnealRadio = gtk_radio_button_new_with_mnemonic_from_widget
                             (GTK_RADIO_BUTTON (toRet -> noAnnealRadio), "_Gibbs annealing");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> gibbsAnnealRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> gibbsAnnealRadio);
 toRet -> nixonAnnealRadio = gtk_radio_button_new_with_mnemonic_from_widget
                             (GTK_RADIO_BUTTON (toRet -> noAnnealRadio), "Ni_xon annealing");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> nixonAnnealRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> nixonAnnealRadio);
 toRet -> generationEntry = CreateEntry ("Generations", GTK_BOX (vBox));
 toRet -> equalEntry = CreateEntry ("Accept equals (percent)", GTK_BOX (vBox));
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), hBox, TRUE, TRUE, 2);
 gtk_widget_show (hBox);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 toRet -> keepCheck = gtk_check_button_new_with_mnemonic ("_Keep actual reconstructions");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> keepCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> keepCheck);
 toRet -> allCheck = gtk_check_button_new_with_mnemonic ("Keep _all reconstructions");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> allCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> allCheck);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 text = g_strdup_printf ("%ld", params . its);
 gtk_entry_set_text (GTK_ENTRY (toRet -> iterEntry), text);
 g_free (text);
 text = g_strdup_printf ("%ld", params . hold);
 gtk_entry_set_text (GTK_ENTRY (toRet -> holdEntry), text);
 g_free (text);
 text = g_strdup_printf ("%ld", params . sectSize);
 gtk_entry_set_text (GTK_ENTRY (toRet -> secSizeEntry), text);
 g_free (text);
 text = g_strdup_printf ("%ld", params . generations);
 gtk_entry_set_text (GTK_ENTRY (toRet -> generationEntry), text);
 g_free (text);
 text = g_strdup_printf ("%ld", params . acceptEqual);
 gtk_entry_set_text (GTK_ENTRY (toRet -> equalEntry), text);
 g_free (text);
 if (params . algorithm & PAGE_SEARCH)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> pageCheck), TRUE);
 if (params . algorithm & FLIP_NODES)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> flipCheck), TRUE);
 if (params . search & CONSTR_SEARCH)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> consCheck), TRUE);
 if (params . algorithm & FIRST_SECTOR)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> startSecRadio), TRUE);
 else if (params . algorithm & FULL_SECTOR)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> secRadio), TRUE);
 else
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> noSecRadio), TRUE);
 if (params . algorithm & BLIND_ANNEAL)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> blindAnnealRadio), TRUE);
 else if (params . algorithm & GIBBS_ANNEAL)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> gibbsAnnealRadio), TRUE);
 else if (params . algorithm & NIXON_ANNEAL)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> nixonAnnealRadio), TRUE);
 else
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> noAnnealRadio), TRUE);
 return toRet;
}

void DestroySearchDialog (SEARCHDIALOG* searchDialog) {
 gtk_widget_destroy (searchDialog -> dialog);
 g_slice_free1 (sizeof (SEARCHDIALOG), searchDialog);
}

REFINEDIALOG* RefineDialog () {
 REFINEDIALOG* toRet;
 GtkWidget* separator;
 GtkWidget* vBox;
 GtkWidget* hBox;
 gchar* text;

 toRet = g_slice_alloc (sizeof (REFINEDIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Refine", GTK_WINDOW (GETMAINWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 hBox = gtk_hbox_new (FALSE, 25);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> simpleRadio = gtk_radio_button_new_with_mnemonic (NULL, "_Simple refinement");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> simpleRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> simpleRadio);
 toRet -> fuseRadio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (toRet -> simpleRadio), "_Fuse reconstructions");
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> fuseRadio, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> fuseRadio);
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 separator = gtk_vseparator_new ();
 gtk_box_pack_start (GTK_BOX (hBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 vBox = gtk_vbox_new (FALSE, 0);
 toRet -> holdEntry = CreateEntry ("Max. Hold (when simple ref.)", GTK_BOX (vBox));
 gtk_box_pack_start (GTK_BOX (hBox), vBox, TRUE, TRUE, 2);
 gtk_widget_show (vBox);
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), hBox, TRUE, TRUE, 2);
 gtk_widget_show (hBox);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 toRet -> pageCheck = gtk_check_button_new_with_mnemonic ("_Page\'s heuristic");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> pageCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> pageCheck);
 toRet -> flipCheck = gtk_check_button_new_with_mnemonic ("_Flip nodes");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> flipCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> flipCheck);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 toRet -> consCheck = gtk_check_button_new_with_mnemonic ("_OR constrained search");
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), toRet -> consCheck, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> consCheck);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 text = g_strdup_printf ("%ld", params . maxHold);
 gtk_entry_set_text (GTK_ENTRY (toRet -> holdEntry), text);
 g_free (text);

 if (params . algorithm & PAGE_SEARCH)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> pageCheck), TRUE);
 if (params . algorithm & FLIP_NODES)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> flipCheck), TRUE);
 if (params . search & CONSTR_SEARCH)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> consCheck), TRUE);
 if (params . algorithm & REC_FUSING)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> fuseRadio), TRUE);
 else
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toRet -> simpleRadio), TRUE);
 return toRet;
}

void DestroyRefineDialog (REFINEDIALOG* refineDialog) {
 gtk_widget_destroy (refineDialog -> dialog);
 g_slice_free1 (sizeof (REFINEDIALOG), refineDialog);
}

static gint CanWindowClose (GtkWidget* widget, gpointer data) {
 SFLAG* progressUp;

 progressUp = (SFLAG*) data;
 return *progressUp;
}

static void OnStopSearch (GtkButton* stopButton, gpointer data) {
 PROGRESSSTRUCT* pBar;

 pBar = (PROGRESSSTRUCT*) data;
 pBar -> isActive = FALSE;
}

SEARCHPROGDLG* SearchProgress (PROGRESSSTRUCT* progress, SFLAG mode) {
 SEARCHPROGDLG* toRet;
 GtkWidget* vBox;
 GtkWidget* label;

 toRet = g_slice_alloc (sizeof (SEARCHPROGDLG));
 toRet -> dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 toRet -> progressUp = TRUE;
 gtk_window_set_title (GTK_WINDOW (toRet -> dialog), "Searching...");
 g_signal_connect (G_OBJECT (toRet -> dialog), "delete_event", G_CALLBACK (CanWindowClose), &toRet -> progressUp);
 gtk_container_border_width (GTK_CONTAINER (toRet -> dialog), 0);
 gtk_window_set_modal (GTK_WINDOW (toRet -> dialog), TRUE);

 vBox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (toRet -> dialog), vBox);
 gtk_widget_show (vBox);
 label = gtk_label_new ("Trees");
 gtk_box_pack_start (GTK_BOX (vBox), label, TRUE, TRUE, 2);
 gtk_widget_show (label);
 toRet -> treeProgress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> treeProgress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> treeProgress);
 label = gtk_label_new ("Iterations");
 gtk_box_pack_start (GTK_BOX (vBox), label, TRUE, TRUE, 2);
 gtk_widget_show (label);
 toRet -> iterProgress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> iterProgress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> iterProgress);
 toRet -> stopButton = gtk_button_new_from_stock (GTK_STOCK_STOP);
 g_signal_connect (G_OBJECT (toRet -> stopButton), "clicked", G_CALLBACK (OnStopSearch), progress);
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> stopButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> stopButton);
 gtk_widget_set_sensitive (toRet -> stopButton, mode);

 toRet -> progressData = progress;
 gtk_widget_show (toRet -> dialog);
 return toRet;
}

gboolean UpdateSearchProgress (gpointer data) {
 SEARCHPROGDLG* prog;
 gchar* text;

 prog = (SEARCHPROGDLG*) data;
 if ((prog -> progressData -> isActive == FALSE) || (prog -> progressData -> actBar1 >= prog -> progressData -> numBar1)) {
   prog -> progressUp = FALSE;
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> treeProgress), 1.0);
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> iterProgress), 1.0);
   gtk_widget_destroy (prog -> dialog);
   g_slice_free1 (sizeof (SEARCHPROGDLG), prog);
   return FALSE;
 }
 text = g_strdup_printf ("Tree %ld of %ld", prog -> progressData -> actBar1, prog -> progressData -> numBar1);
 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (prog -> treeProgress), text);
 g_free (text);
 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> treeProgress),
                                            (gdouble) prog -> progressData -> actBar1 / prog -> progressData -> numBar1);
 text = g_strdup_printf ("Iteration %ld of %ld", prog -> progressData -> actBar2, prog -> progressData -> numBar2);
 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (prog -> iterProgress), text);
 g_free (text);
 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> iterProgress),
                                            (gdouble) prog -> progressData -> actBar2 / prog -> progressData -> numBar2);
 return TRUE;
}

REFINEPROGDLG* RefineProgress (PROGRESSSTRUCT* progress, SFLAG mode) {
 REFINEPROGDLG* toRet;
 GtkWidget* vBox;
 GtkWidget* label;

 toRet = g_slice_alloc (sizeof (REFINEPROGDLG));
 toRet -> dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 toRet -> progressUp = TRUE;
 gtk_window_set_title (GTK_WINDOW (toRet -> dialog), "Refining...");
 g_signal_connect (G_OBJECT (toRet -> dialog), "delete_event", G_CALLBACK (CanWindowClose), &toRet -> progressUp);
 gtk_container_border_width (GTK_CONTAINER (toRet -> dialog), 0);
 gtk_window_set_modal (GTK_WINDOW (toRet -> dialog), TRUE);

 vBox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (toRet -> dialog), vBox);
 gtk_widget_show (vBox);
 label = gtk_label_new ("Trees");
 gtk_box_pack_start (GTK_BOX (vBox), label, TRUE, TRUE, 2);
 gtk_widget_show (label);
 toRet -> treeProgress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> treeProgress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> treeProgress);
 label = gtk_label_new ("Refinements");
 gtk_box_pack_start (GTK_BOX (vBox), label, TRUE, TRUE, 2);
 gtk_widget_show (label);
 toRet -> refineProgress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> refineProgress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> refineProgress);
 toRet -> stopButton = gtk_button_new_from_stock (GTK_STOCK_STOP);
 g_signal_connect (G_OBJECT (toRet -> stopButton), "clicked", G_CALLBACK (OnStopSearch), progress);
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> stopButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> stopButton);
 gtk_widget_set_sensitive (toRet -> stopButton, mode);
 gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (toRet -> refineProgress), 0.10);

 toRet -> progressData = progress;
 gtk_widget_show (toRet -> dialog);
 return toRet;
}

gboolean UpdateRefineProgress (gpointer data) {
 REFINEPROGDLG* prog;
 gchar* text;

 prog = (REFINEPROGDLG*) data;
 if ((prog -> progressData -> isActive == FALSE) || (prog -> progressData -> actBar1 >= prog -> progressData -> numBar1)) {
   prog -> progressUp = FALSE;
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> treeProgress), 1.0);
   gtk_widget_destroy (prog -> dialog);
   g_slice_free1 (sizeof (REFINEPROGDLG), prog);
   return FALSE;
 }
 text = g_strdup_printf ("Tree %ld of %ld", prog -> progressData -> actBar1, prog -> progressData -> numBar1);
 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (prog -> treeProgress), text);
 g_free (text);
 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> treeProgress),
                                            (gdouble) prog -> progressData -> actBar1 / prog -> progressData -> numBar1);
 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (prog -> refineProgress));
 return TRUE;
}

void DestroyParsingProgressDialog (PARSINGPROGDLG* toDel) {
 gtk_widget_destroy (toDel -> dialog);
 g_slice_free1 (sizeof (PARSINGPROGDLG), toDel);
}

PARSINGPROGDLG* ParsingProgress (PROGRESSSTRUCT* progress) {
 PARSINGPROGDLG* toRet;
 GtkWidget* vBox;
 GtkWidget* label;

 toRet = g_slice_alloc (sizeof (PARSINGPROGDLG));
 toRet -> dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 toRet -> progressUp = TRUE;
 gtk_window_set_title (GTK_WINDOW (toRet -> dialog), "Parsing file...");
 g_signal_connect (G_OBJECT (toRet -> dialog), "delete_event", G_CALLBACK (CanWindowClose), &toRet -> progressUp);
 gtk_container_border_width (GTK_CONTAINER (toRet -> dialog), 0);
 gtk_window_set_modal (GTK_WINDOW (toRet -> dialog), TRUE);

 vBox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (toRet -> dialog), vBox);
 gtk_widget_show (vBox);
 label = gtk_label_new ("Parsing...");
 gtk_box_pack_start (GTK_BOX (vBox), label, TRUE, TRUE, 2);
 gtk_widget_show (label);
 toRet -> fileProgress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> fileProgress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> fileProgress);

 toRet -> progressData = progress;
 gtk_widget_show (toRet -> dialog);
 return toRet;
}

gboolean UpdateParsingProgress (gpointer data) {
 PARSINGPROGDLG* prog;

 prog = (PARSINGPROGDLG*) data;
 if ((prog -> progressData -> isActive == FALSE) || (prog -> progressData -> actBar1 >= prog -> progressData -> numBar1)) {
   prog -> progressUp = FALSE;
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> fileProgress), 1.0);
   gtk_widget_destroy (prog -> dialog);
   g_slice_free1 (sizeof (PARSINGPROGDLG), prog);
   return FALSE;
 }
 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog -> fileProgress),
                                            (gdouble) prog -> progressData -> actBar1 / prog -> progressData -> numBar1);
 return TRUE;
}

void DestroyActivityProgressDialog (ACTIVPROGDLG* toDel) {
 gtk_widget_destroy (toDel -> dialog);
 g_slice_free1 (sizeof (ACTIVPROGDLG), toDel);
}

ACTIVPROGDLG* ActivityProgress (gchar* title) {
 ACTIVPROGDLG* toRet;
 GtkWidget* vBox;

 toRet = g_slice_alloc (sizeof (ACTIVPROGDLG));
 toRet -> dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 toRet -> progressUp = TRUE;
 gtk_window_set_title (GTK_WINDOW (toRet -> dialog), title);
 g_signal_connect (G_OBJECT (toRet -> dialog), "delete_event", G_CALLBACK (CanWindowClose), &toRet -> progressUp);
 gtk_container_border_width (GTK_CONTAINER (toRet -> dialog), 0);
 gtk_window_set_modal (GTK_WINDOW (toRet -> dialog), TRUE);

 vBox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (toRet -> dialog), vBox);
 gtk_widget_show (vBox);
 toRet -> progress = gtk_progress_bar_new ();
 gtk_box_pack_start (GTK_BOX (vBox), toRet -> progress, TRUE, TRUE, 2);
 gtk_widget_show (toRet -> progress);

 gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (toRet -> progress), 0.10);
 gtk_widget_show (toRet -> dialog);
 return toRet;
}

gboolean UpdateActivityProgress (gpointer data) {
 ACTIVPROGDLG* prog;

 prog = (ACTIVPROGDLG*) data;
 if (prog -> progressUp == FALSE) {
   gtk_widget_destroy (prog -> dialog);
   g_slice_free1 (sizeof (ACTIVPROGDLG), prog);
   return FALSE;
 }
 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (prog -> progress));
 return TRUE;
}

static void PutGeo (GEOREFBROWSERDLG* dlg) {
 TERMINAL* term;
 gchar* text;
 GEOREF* geo;

 geo = dlg -> actGeo;
 text = g_strdup_printf ("%.4f", geo -> lat);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (dlg -> latEntry), text);
 g_free (text);
 text = g_strdup_printf ("%.4f", geo -> lon);
 CheckRealStr (text);
 gtk_entry_set_text (GTK_ENTRY (dlg -> lonEntry), text);
 g_free (text);
 term = (TERMINAL*) geo -> sp -> data;
 gtk_entry_set_text (GTK_ENTRY (dlg -> spEntry), term -> name);
 if (geo -> name != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> nameEntry), geo -> name);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> nameEntry), "");
 if (geo -> collec != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> collecEntry), geo -> collec);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> collecEntry), "");
 if (geo -> catalog != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> catalogEntry), geo -> catalog);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> catalogEntry), "");
 if (geo -> url != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> urlEntry), geo -> url);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> urlEntry), "");
 if (geo -> reference != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> referenceEntry), geo -> reference);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> referenceEntry), "");
 if (geo -> identifier != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> identifierEntry), geo -> identifier);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> identifierEntry), "");
 if (geo -> sampleDate != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> sampleEntry), geo -> sampleDate);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> sampleEntry), "");
 if (geo -> collector != NULL)
   gtk_entry_set_text (GTK_ENTRY (dlg -> collectorEntry), geo -> collector);
 else
   gtk_entry_set_text (GTK_ENTRY (dlg -> collectorEntry), "");
 if (g_list_next (geo -> list) != NULL)
   gtk_widget_set_sensitive (dlg -> nextButton, TRUE);
 else
   gtk_widget_set_sensitive (dlg -> nextButton, FALSE);
 if (g_list_previous (geo -> list) != NULL)
   gtk_widget_set_sensitive (dlg -> prevButton, TRUE);
 else
   gtk_widget_set_sensitive (dlg -> prevButton, FALSE);
}

static void OnButtonPrevGeo (GtkButton* prevButton, gpointer data) {
 GEOREFBROWSERDLG* dlg;
 GList* geoList;

 dlg = (GEOREFBROWSERDLG*) data;
 geoList = g_list_previous (dlg -> actGeo -> list);
 dlg -> actGeo = (GEOREF*) geoList -> data;
 PutGeo (dlg);
}

static void OnButtonNextGeo (GtkButton* nextButton, gpointer data) {
 GEOREFBROWSERDLG* dlg;
 GList* geoList;

 dlg = (GEOREFBROWSERDLG*) data;
 geoList = g_list_next (dlg -> actGeo -> list);
 dlg -> actGeo = (GEOREF*) geoList -> data;
 PutGeo (dlg);
}

static void OnButtonApplyGeo (GtkButton* applyButton, gpointer data) {
 GEOREFBROWSERDLG* dlg;
 SFLAG change;
 SREAL nuLat, nuLon;
 gchar* entry;
 GEOREF* geo;
 TERMINAL* actTerm;

 dlg = (GEOREFBROWSERDLG*) data;
 change = FALSE;
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> latEntry)));
 SetCommandLine (entry);
 g_free (entry);
 geo = dlg -> actGeo;
 if (GetCmdReal (&nuLat) != FALSE) {
   if ((nuLat > -90.0000) && (nuLat < 90.0000))
     change = TRUE;
   else
     nuLat = geo -> lat;
 }
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> lonEntry)));
 SetCommandLine (entry);
 g_free (entry);
 if (GetCmdReal (&nuLon) != FALSE) {
   if ((nuLon > -180.0000) && (nuLon < 180.0000))
     change = TRUE;
  else
     nuLon = geo -> lon;
 }
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> nameEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> name))) {
   actTerm = (TERMINAL*) geo -> sp -> data;
   geo -> name = AddSynonim (actTerm, entry);
 }
 g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> collecEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> collec))) {
   g_free (geo -> collec);
   geo -> collec = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> catalogEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> catalog))) {
   g_free (geo -> catalog);
   geo -> catalog = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> urlEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> url))) {
   g_free (geo -> url);
   geo -> url = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> referenceEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> reference))) {
   g_free (geo -> reference);
   geo -> reference = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> identifierEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> identifier))) {
   g_free (geo -> identifier);
   geo -> identifier = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> sampleEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> sampleDate))) {
   g_free (geo -> sampleDate);
   geo -> sampleDate = entry;
 }
 else
   g_free (entry);
 entry = g_strdup_printf (gtk_entry_get_text (GTK_ENTRY (dlg -> collectorEntry)));
 if ((strlen (entry)) && (g_strcmp0 (entry, geo -> collector))) {
   g_free (geo -> collector);
   geo -> collector = entry;
 }
 else
   g_free (entry);
 if (change == TRUE) {
   geo -> lat = nuLat;
   geo -> lon = nuLon;
   geo -> inclination = FROMLATTOINC (nuLat);
   geo -> azimuth = FROMLONTOAZM (nuLon);
   UpdateLimits (geo);
   PaintNewGeoRef (geo);
 }
 gtk_widget_destroy (dlg -> dialog);
 g_slice_free1 (sizeof (GEOREFBROWSERDLG), dlg);
}

static void OnButtonDelGeo (GtkButton* delButton, gpointer data) {
 GEOREFBROWSERDLG* dlg;
 GEOREF* geo;

 dlg = (GEOREFBROWSERDLG*) data;
 geo = dlg -> actGeo;
 DeleteGeoRef (geo);
 ChangeGeo ();
 gtk_widget_destroy (dlg -> dialog);
 g_slice_free1 (sizeof (GEOREFBROWSERDLG), dlg);
}

static void OnButtonClose (GtkButton* closeButton, gpointer data) {
 GEOREFBROWSERDLG* dlg;

 dlg = (GEOREFBROWSERDLG*) data;
 gtk_widget_destroy (dlg -> dialog);
 g_slice_free1 (sizeof (GEOREFBROWSERDLG), dlg);
}

static gint OnCloseBrowser (GtkWidget* widget, gpointer data) {
 return TRUE;
}

GEOREFBROWSERDLG* GeoRefBrowser (GEOREF* geo, SFLAG mode) {
 GEOREFBROWSERDLG* toRet;
 GtkWidget* vBox;
 GtkWidget* hBox;
 GtkWidget* extraBox;
 GtkWidget* buttonBox;
 GtkWidget* separator;
 GtkWidget* button;

 toRet = g_slice_alloc (sizeof (GEOREFBROWSERDLG));
 toRet -> dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 gtk_window_set_title (GTK_WINDOW (toRet -> dialog), "Record browser");
 g_signal_connect (G_OBJECT (toRet -> dialog), "delete_event", G_CALLBACK (OnCloseBrowser), NULL);
 gtk_container_border_width (GTK_CONTAINER (toRet -> dialog), 0);
 gtk_window_set_modal (GTK_WINDOW (toRet -> dialog), TRUE);
 vBox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (toRet -> dialog), vBox);
 gtk_widget_show (vBox);


 hBox = gtk_hbox_new (FALSE, 10);
 extraBox = gtk_vbox_new (FALSE, 0);
 toRet -> spEntry = CreateEntry ("Terminal", GTK_BOX (extraBox));
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (extraBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 buttonBox = gtk_hbox_new (TRUE, 5);
 toRet -> prevButton = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
 g_signal_connect (G_OBJECT (toRet -> prevButton), "clicked", G_CALLBACK (OnButtonPrevGeo), toRet);
 gtk_box_pack_start (GTK_BOX (buttonBox), toRet -> prevButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> prevButton);
 toRet -> nextButton = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
 g_signal_connect (G_OBJECT (toRet -> nextButton), "clicked", G_CALLBACK (OnButtonNextGeo), toRet);
 gtk_box_pack_start (GTK_BOX (buttonBox), toRet -> nextButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> nextButton);
 gtk_box_pack_start (GTK_BOX (extraBox), buttonBox, FALSE, TRUE, 2);
 gtk_widget_show (buttonBox);

 toRet -> latEntry = CreateEntry ("Latitude", GTK_BOX (extraBox));
 toRet -> lonEntry = CreateEntry ("Longitude", GTK_BOX (extraBox));
 gtk_box_pack_start (GTK_BOX (hBox), extraBox, FALSE, TRUE, 2);
 gtk_widget_show (extraBox);
 separator = gtk_vseparator_new ();
 gtk_box_pack_start (GTK_BOX (hBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 extraBox = gtk_vbox_new (FALSE, 0);
 toRet -> nameEntry = CreateEntry ("Record name", GTK_BOX (extraBox));
 toRet -> collecEntry = CreateEntry ("Collection", GTK_BOX (extraBox));
 toRet -> catalogEntry = CreateEntry ("Catalogue code", GTK_BOX (extraBox));
 toRet -> urlEntry = CreateEntry ("Url", GTK_BOX (extraBox));
 toRet -> referenceEntry = CreateEntry ("Reference", GTK_BOX (extraBox));
 gtk_box_pack_start (GTK_BOX (hBox), extraBox, FALSE, TRUE, 2);
 gtk_widget_show (extraBox);
 gtk_box_pack_start (GTK_BOX (vBox), hBox, FALSE, TRUE, 2);
 gtk_widget_show (hBox);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (vBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 hBox = gtk_hbox_new (FALSE, 10);
 extraBox = gtk_vbox_new (FALSE, 0);
 toRet -> identifierEntry = CreateEntry ("Identified by", GTK_BOX (extraBox));
 toRet -> collectorEntry = CreateEntry ("Collector", GTK_BOX (extraBox));
 gtk_box_pack_start (GTK_BOX (hBox), extraBox, FALSE, TRUE, 2);
 gtk_widget_show (extraBox);
 separator = gtk_vseparator_new ();
 gtk_box_pack_start (GTK_BOX (hBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 extraBox = gtk_vbox_new (FALSE, 0);
 toRet -> sampleEntry = CreateEntry ("Sample date", GTK_BOX (extraBox));
 gtk_box_pack_start (GTK_BOX (hBox), extraBox, FALSE, TRUE, 2);
 gtk_widget_show (extraBox);
 gtk_box_pack_start (GTK_BOX (vBox), hBox, FALSE, TRUE, 2);
 gtk_widget_show (hBox);
 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (vBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 hBox = gtk_hbox_new (FALSE, 10);
 toRet -> applyButton = gtk_button_new_from_stock (GTK_STOCK_APPLY);
 g_signal_connect (G_OBJECT (toRet -> applyButton), "clicked", G_CALLBACK (OnButtonApplyGeo), toRet);
 gtk_box_pack_start (GTK_BOX (hBox), toRet -> applyButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> applyButton);
 toRet -> delButton = gtk_button_new_from_stock (GTK_STOCK_DELETE);
 g_signal_connect (G_OBJECT (toRet -> delButton), "clicked", G_CALLBACK (OnButtonDelGeo), toRet);
 gtk_box_pack_start (GTK_BOX (hBox), toRet -> delButton, FALSE, TRUE, 2);
 gtk_widget_show (toRet -> delButton);
 gtk_widget_set_sensitive (toRet -> applyButton, mode);
 gtk_widget_set_sensitive (toRet -> delButton, mode);
 separator = gtk_vseparator_new ();
 gtk_box_pack_start (GTK_BOX (hBox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);
 button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (OnButtonClose), toRet);
 gtk_box_pack_start (GTK_BOX (hBox), button, FALSE, TRUE, 2);
 gtk_widget_show (button);
 gtk_box_pack_start (GTK_BOX (vBox), hBox, FALSE, TRUE, 2);
 gtk_widget_show (hBox);

 toRet -> actGeo = geo;

 gtk_editable_set_editable (GTK_EDITABLE (toRet -> spEntry), FALSE);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> nameEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> latEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> lonEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> collecEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> catalogEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> referenceEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> identifierEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> sampleEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> collectorEntry), mode);

 PutGeo (toRet);
 gtk_widget_show (toRet -> dialog);

 return toRet;
}

NODEDATADIALOG* NodeDataDialog (GNode* node, SFLAG mode) {
 NODEDATADIALOG* toRet;
 GtkWidget* separator;
 PHYLONODE* actNode;
 gchar* text;

 toRet = g_slice_alloc (sizeof (NODEDATADIALOG));
 toRet -> dialog = gtk_dialog_new_with_buttons ("Node", GTK_WINDOW (GETTREEWIN),
                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

 toRet -> nameEntry = CreateEntry ("Node name", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 toRet -> ageEntry = CreateEntry ("Node age", GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox));

 separator = gtk_hseparator_new ();
 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (toRet -> dialog) -> vbox), separator, TRUE, TRUE, 2);
 gtk_widget_show (separator);

 actNode = (PHYLONODE*) node -> data;
 if (actNode -> name != NULL)
   text = g_strdup_printf (actNode -> name);
 else
   text = g_strdup_printf ("unnamed");
 gtk_entry_set_text (GTK_ENTRY (toRet -> nameEntry), text);
 g_free (text);
  text = g_strdup_printf ("%ld", actNode -> minAge);
 gtk_entry_set_text (GTK_ENTRY (toRet -> ageEntry), text);
 g_free (text);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> nameEntry), mode);
 gtk_editable_set_editable (GTK_EDITABLE (toRet -> ageEntry), mode);
 return toRet;
}

void DestroyNodeDataDialog (NODEDATADIALOG* toDel) {
 gtk_widget_destroy (toDel -> dialog);
 g_slice_free1 (sizeof (NODEDATADIALOG), toDel);
}
